﻿/// /////////////////////////////////////////////
// 单元名 : UserManagerForm
// 作者 : Hawk
// 单元描述 :
// 日期 : 2023-09-15
/// /////////////////////////////////////////////

{$IFDEF FPC}
{$H+}
{$MODE DELPHI}
{$ENDIF}
unit UserManagerForm;

interface

uses
{$IFnDEF FPC}
  Windows,
{$ELSE}
  LCLIntf, LCLType, LMessages,
{$ENDIF}
  Messages, SysUtils, Classes, Graphics, Controls, Forms, MsgBaseForm, ComCtrls, StdCtrls, unitAAACommon,
  unitCommonDataStruct, unitMsgObj, Buttons, ExtCtrls, unitClientBuffer, unitPriority;

type
  TPRIORITY_REC = packed record
    UIObj: TCheckBox;
    FuncObj: TFuncInfo;
    FuncMask: Longword;
  end;

  TfrmMsgBaseUserManager = class(TfrmMsgBase)
    PageControl1: TPageControl;
    TabSheet3: TTabSheet;
    lbUserList: TListBox;
    BitBtnSaveUser: TBitBtn;
    BitBtnDelUser: TBitBtn;
    PageControl2: TPageControl;
    TabSheet1: TTabSheet;
    Label4: TLabel;
    EditUserID: TEdit;
    EditUserName: TEdit;
    EditUserFullName: TEdit;
    EditIdleTime: TEdit;
    Edit1: TEdit;
    TabSheet2: TTabSheet;
    Label1: TLabel;
    Label2: TLabel;
    ListBoxAllowIPs: TListBox;
    ListBoxDenyIPs: TListBox;
    Label3: TLabel;
    BitBtnDelFromAllowIP: TBitBtn;
    BitBtnDelFromDenyIP: TBitBtn;
    EditIPAddr: TEdit;
    BitBtnAddAllowIP: TBitBtn;
    BitBtnAddDenyIP: TBitBtn;
    TabSheet4: TTabSheet;
    edtPersonID: TEdit;
    edtPhone: TEdit;
    Panel1: TPanel;
    imgEmpPhoto: TImage;
    procedure lbUserListClick(Sender: TObject);
    procedure BitBtnSaveUserClick(Sender: TObject);
    procedure BitBtnDelFromAllowIPClick(Sender: TObject);
    procedure BitBtnAddAllowIPClick(Sender: TObject);
  private
    { Private declarations }
    FCurUser: TUserInfo;

    procedure ResetAllowAndDenyIPs;
    procedure AuthIPsToUI(authIP: TAuthorizedSourceIP);
    function StrToIPs(s: string; var ips, ipe: Longword): ERRCODE;
    function UIToAuthIPs: TAuthorizedSourceIP;

    procedure ProcessRecvFuncInfo(msg: TMsg);
    procedure ProcUserList(msg: TMsg);
  protected
    procedure DoProcMsg(msg: TMsg); override;
  public
    { Public declarations }
    procedure FuncStart; override;
    procedure FuncStop; override;
  end;

implementation

uses unitObjPool, unitMisc, unitErrCodeDef;

const
  ID_FUNCTABLE: TID_OBJ = (IDDetail: (ObjType: 5; SubType: $86;
    SubID: (IDBuf: ($65, $E5, $3A, $DF, $55, $4D, $AC, $A9, $4A, $D1, $82, $93, $73, $EC))));
  ID_USERLIST: TID_OBJ = (IDDetail: (ObjType: 5; SubType: $86;
    SubID: (IDBuf: ($65, $E5, $3A, $DF, $55, $4D, $AC, $A9, $4A, $D1, $82, $93, $73, $ED))));

{$IFnDEF FPC}
  {$R *.dfm}
{$ELSE}
  {$R *.lfm}
{$ENDIF}
  { TfrmMsgBaseUserManager }

procedure TfrmMsgBaseUserManager.AuthIPsToUI(authIP: TAuthorizedSourceIP);
var
  i: Integer;
begin
  if authIP <> nil then
  begin
    for i := 0 to authIP.AllowIPCount - 1 do
      ListBoxAllowIPs.Items.Add(authIP.AllowIPS[i]);
    for i := 0 to authIP.DenyIPCount - 1 do
      ListBoxDenyIPs.Items.Add(authIP.DenyIPS[i]);
  end;
end;

procedure TfrmMsgBaseUserManager.BitBtnAddAllowIPClick(Sender: TObject);
var
  s: string;
begin
  if (EditIPAddr.Text <> '') then
  begin
    s := Trim(EditIPAddr.Text);
    if Sender = BitBtnAddAllowIP then
      ListBoxAllowIPs.Items.Add(s);
    if Sender = BitBtnAddDenyIP then
      ListBoxDenyIPs.Items.Add(s);
  end;
end;

procedure TfrmMsgBaseUserManager.BitBtnDelFromAllowIPClick(Sender: TObject);
var
  lb: TListBox;
  idx: Integer;
begin
  lb := nil;
  if Sender = BitBtnDelFromAllowIP then
    lb := ListBoxAllowIPs;
  if Sender = BitBtnDelFromDenyIP then
    lb := ListBoxDenyIPs;
  if (lb <> nil) and (lb.ItemIndex <> -1) then
  begin
    idx := lb.ItemIndex;
    lb.Items.Delete(lb.ItemIndex);
    if lb.Items.Count > idx then
      lb.ItemIndex := idx
    else
      lb.ItemIndex := lb.Items.Count - 1;
  end;
end;

procedure TfrmMsgBaseUserManager.BitBtnSaveUserClick(Sender: TObject);
var
  ui: TUserInfo;
begin
  if lbUserList.ItemIndex <> -1 then
  begin
    if CheckUIElement(EditUserName, [I_UICHECKTYPE_NONEMPTY], '登录名不能为空') then
      if CheckUIElement(EditUserFullName, [I_UICHECKTYPE_NONEMPTY], '用户全名不能为空') then
        if CheckUIElement(EditIdleTime, [I_UICHECKTYPE_INTRANGE], '') then
        begin
          ui := ObjPool.GetObj(TUserInfo, Self);
          if FCurUser <> nil then
            ui.ObjID := FCurUser.ObjID;
          ui.UserName := Trim(EditUserName.Text);
          ui.FullName := Trim(EditUserFullName.Text);
          ui.IdleTimeOut := StrToInt(EditIdleTime.Text);
          ui.AddObj(UIToAuthIPs);
        end;
  end;
end;

procedure TfrmMsgBaseUserManager.DoProcMsg(msg: TMsg);
begin
  case msg.MsgID of
    MESID_ALL_RETURNFUNC_INFO:
      ProcessRecvFuncInfo(msg);
    MESID_AAA_USERLIST:
      ProcUserList(msg);
  else
    inherited;
  end;
end;

procedure TfrmMsgBaseUserManager.FuncStart;
begin
  inherited;
  FCurUser := nil;
  AddBindInfo(ID_USERSTABLE, PeerHost, lbUserList, nil, nil, nil, nil, nil, nil, nil);
end;

procedure TfrmMsgBaseUserManager.FuncStop;
begin
  ConfigObj.FindItem(ID_FUNCTABLE).Free;
  inherited;
end;

procedure TfrmMsgBaseUserManager.lbUserListClick(Sender: TObject);
begin
  EditUserID.Text := '';
  EditUserName.Text := '';
  EditUserFullName.Text := '';
  EditIdleTime.Text := '';
  ResetAllowAndDenyIPs;
  if lbUserList.ItemIndex <> -1 then
  begin
    FCurUser := TUserInfo(lbUserList.Items.Objects[lbUserList.ItemIndex]);
    if FCurUser <> nil then
    begin
      EditUserID.Text := FCurUser.ObjID.ToString;
      EditUserName.Text := FCurUser.UserName;
      EditUserFullName.Text := FCurUser.FullName;
      EditIdleTime.Text := IntToStr(FCurUser.IdleTimeOut);
      AuthIPsToUI(FCurUser.Param(TAuthorizedSourceIP));
    end;
  end;
end;

procedure TfrmMsgBaseUserManager.ProcessRecvFuncInfo(msg: TMsg);
var
  fi: TFuncInfo;
begin
  while msg.Count > 0 do
  begin
    fi := msg.Param(TFuncInfo);
    if fi <> nil then
    begin
      ObjPool.ReturnObj(fi, Self);
    end
    else
      Break;
  end;
end;

procedure TfrmMsgBaseUserManager.ProcUserList(msg: TMsg);
var
  sl: TClientObjList;
begin
  sl := TClientObjList(msg.FindItemLowerLevel(ID_USERSTABLE));
  if sl <> nil then
    TempTableStores.AddTable(msg.SourceObjID.IDDetail.SvrMdl.HostID, sl);
end;

procedure TfrmMsgBaseUserManager.ResetAllowAndDenyIPs;
begin
  ListBoxAllowIPs.Clear;
  ListBoxDenyIPs.Clear;
  EditIPAddr.Text := '';
end;

function TfrmMsgBaseUserManager.StrToIPs(s: string; var ips, ipe: Longword): ERRCODE;
var
  i: Integer;
  ss: string;

  procedure DivStr(idx: Integer);
  begin
    ss := Trim(Copy(s, 1, idx - 1));
    Delete(s, 1, idx);
    s := Trim(s);
  end;

begin
  Result := ERRCODE_NOERROR;
  ips := 0;
  ipe := 0;
  i := Pos('-', s);
  if i <> 0 then
  begin
    DivStr(i);
    ips := StrToIPV4(ss);
    ipe := StrToIPV4(s);
    if ips > ipe then
      Result := ERRCODE_PARAMERROR;
  end
  else
  begin
    i := Pos('/', s);
    if i <> 0 then
    begin
      DivStr(i);
      ips := StrToIPV4(ss);
    end
    else
    begin
      ips := StrToIPV4(s);
      ipe := ips;
    end;
  end;
end;

function TfrmMsgBaseUserManager.UIToAuthIPs: TAuthorizedSourceIP;
var
  i: Integer;
  ips, ipe: Longword;
begin
  if (ListBoxAllowIPs.Count > 0) or (ListBoxDenyIPs.Count > 0) then
  begin
    Result := ObjPool.GetObj(TAuthorizedSourceIP, Self);
    for i := 0 to ListBoxAllowIPs.Items.Count - 1 do
    begin
      if StrToIPs(Trim(ListBoxAllowIPs.Items.Strings[i]), ips, ipe) = ERRCODE_NOERROR then
        Result.AddAllowIP(ips, ipe);
    end;
    for i := 0 to ListBoxDenyIPs.Items.Count - 1 do
    begin
      if StrToIPs(Trim(ListBoxDenyIPs.Items.Strings[i]), ips, ipe) = ERRCODE_NOERROR then
        Result.AddDenyIP(ips, ipe);
    end;
    if (Result.AllowIPCount = 0) and (Result.DenyIPCount = 0) then
    begin
      ObjPool.ReturnObj(Result, Self);
      Result := nil;
    end;
  end
  else
    Result := nil;
end;

initialization

RegFuncClass(HOSTID_ALLMASK, '账户管理', '提供账户管理界面', TfrmMsgBaseUserManager);

end.
